/*:
-------------------------------------------------------------------------
@title Custom Page Conditions
@author Hime
@date Oct 24, 2015
-------------------------------------------------------------------------
@plugindesc 自定义事件页面条件。
@help 
-------------------------------------------------------------------------
== 描述 ==

事件条件可以根据事件页面左边的条件来定义，事件的各种出现条件。
官方 RPG Maker 提供5种不同的事件出现条件:

- 开关 ON
- 变量不少于 值
- 独立开关 ON
- 持有该道具时
- 角色在队伍时

但是，如果你想要设置一个于上面不同的出现条件时，本插件提供了
一个简单的方法来让你定义事件的出现条件，没有做不到，只有你想
不到。

== 使用条款 ==

- 免费使用在非商业用途
- 商业用途必须联系 Hime 
- Facebook https://www.facebook.com/himeworkscom
 
== 使用 == 

在要创建自定义出现条件的事件开头，插入下面这段标签。

  <page condition>
  
在这个标签下面创建一个条件分支，这个条件将做为这个事件的出现条件.
也可以重复以上动作来创建非常多的条件.


-自颖叔の汉化
-------------------------------------------------------------------------
 */  
var TH = TH || {};
TH.CustomPageConditions = TH.CustomPageConditions || {};

(function ($) {

  $.evalCustomPageCondition = function(cmd, mapId, eventId) {
    var params = cmd.parameters;
    var result = false;
    switch (params[0]) {
    case 0:  // Switch
        result = ($gameSwitches.value(params[1]) === (params[2] === 0));
        break;
    case 1:  // Variable
        var value1 = $gameVariables.value(params[1]);
        var value2;
        if (params[2] === 0) {
            value2 = params[3];
        } else {
            value2 = $gameVariables.value(params[3]);
        }
        switch (params[4]) {
        case 0:  // Equal to
            result = (value1 === value2);
            break;
        case 1:  // Greater than or Equal to
            result = (value1 >= value2);
            break;
        case 2:  // Less than or Equal to
            result = (value1 <= value2);
            break;
        case 3:  // Greater than
            result = (value1 > value2);
            break;
        case 4:  // Less than
            result = (value1 < value2);
            break;
        case 5:  // Not Equal to
            result = (value1 !== value2);
            break;
        }
        break;
    case 2:  // Self Switch
        if (eventId > 0) {
            var key = [mapId, eventId, params[1]];
            console.log(key);
            result = ($gameSelfSwitches.value(key) === (params[2] === 0));
        }
        break;
    case 3:  // Timer
        if ($gameTimer.isWorking()) {
            if (params[2] === 0) {
                result = ($gameTimer.seconds() >= params[1]);
            } else {
                result = ($gameTimer.seconds() <= params[1]);
            }
        }
        break;
    case 4:  // Actor
        var actor = $gameActors.actor(params[1]);
        if (actor) {
            var n = params[3];
            switch (params[2]) {
            case 0:  // In the Party
                result = $gameParty.members().contains(actor);
                break;
            case 1:  // Name
                console.log(actor.name());
                result = (actor.name() === n);
                break;
            case 2:  // Class
                result = actor.isClass($dataClasses[n]);
                break;
            case 3:  // Skill
                result = actor.isLearnedSkill(n);
                break;
            case 4:  // Weapon
                result = actor.hasWeapon($dataWeapons[n]);
                break;
            case 5:  // Armor
                result = actor.hasArmor($dataArmors[n]);
                break;
            case 6:  // State
                result = actor.isStateAffected(n);
                break;
            }
        }
        break;
    case 5:  // Enemy
        var enemy = $gameTroop.members()[params[1]];
        if (enemy) {
            switch (params[2]) {
            case 0:  // Appeared
                result = enemy.isAlive();
                break;
            case 1:  // State
                result = enemy.isStateAffected(params[3]);
                break;
            }
        }
        break;
    case 6:  // Character
        var character = this.character(params[1]);
        if (character) {
            result = (character.direction() === params[2]);
        }
        break;
    case 7:  // Gold
        switch (params[2]) {
        case 0:  // Greater than or equal to
            result = ($gameParty.gold() >= params[1]);
            break;
        case 1:  // Less than or equal to
            result = ($gameParty.gold() <= params[1]);
            break;
        case 2:  // Less than
            result = ($gameParty.gold() < params[1]);
            break;
        }
        break;
    case 8:  // Item
        result = $gameParty.hasItem($dataItems[params[1]]);
        break;
    case 9:  // Weapon
        result = $gameParty.hasItem($dataWeapons[params[1]], params[2]);
        break;
    case 10:  // Armor
        result = $gameParty.hasItem($dataArmors[params[1]], params[2]);
        break;
    case 11:  // Button
        result = Input.isPressed(params[1]);
        break;
    case 12:  // Script
        result = !!eval(params[1]);
        break;
    case 13:  // Vehicle
        result = ($gamePlayer.vehicle() === $gameMap.vehicle(params[1]));
        break;
    }
    return result;
  }

  var TH_CustomPageConditions_Game_Event_meetsConditions = Game_Event.prototype.meetsConditions;
  Game_Event.prototype.meetsConditions = function(page) {
    var res = TH_CustomPageConditions_Game_Event_meetsConditions.call(this, page);
    if (!res) {
      return false;
    }
    res = this.meetsCustomConditions(page);
    if (!res) {
      return false;
    }
    return true;
  };
  
  /*
   * Determines whether all custom page conditions have been met.
   */
  Game_Event.prototype.meetsCustomConditions = function(page) {
    if (page._customPageConditions === undefined) {
      this.loadCustomPageConditions(page);
    }
    var res;
    for (var i = 0; i < page._customPageConditions.length; i++) {
      res = TH.CustomPageConditions.evalCustomPageCondition(page._customPageConditions[i], this._mapId, this._eventId);
      if (res === false) {
        return res;
      }
    }
    return true;
  };
  
  /*
   * Go through event commands looking for page conditions
   */
  Game_Event.prototype.loadCustomPageConditions = function(page) {
    page._customPageConditions = [];
    var cmd, nextCmd;
    for (var i = 0; i < page.list.length; i++) {
      cmd = page.list[i];
      nextCmd = page.list[i+1];
      if (cmd.code === 108 && cmd.parameters[0].includes("<出现条件>") && nextCmd.code === 111) {
        page._customPageConditions.push(nextCmd)
      }
    }
  };
  
  /*
   * Update methods to refresh the map
   */    
  var TH_CustomPageConditions_GameParty_gainGold = Game_Party.prototype.gainGold;
  Game_Party.prototype.gainGold = function(amount) {
    TH_CustomPageConditions_GameParty_gainGold.call(this, amount)
    $gameMap.requestRefresh();
  };
  
  var TH_CustomPageConditions_GameActor_setName = Game_Actor.prototype.setName;
  Game_Actor.prototype.setName = function(name) {  
    TH_CustomPageConditions_GameActor_setName.call(this, name)
    $gameMap.requestRefresh();
  };
  
  var TH_CustomPageConditions_GameActor_changeClass = Game_Actor.prototype.changeClass;
  Game_Actor.prototype.changeClass = function(classId, keepExp) {
    TH_CustomPageConditions_GameActor_changeClass.call(this, classId, keepExp);
    $gameMap.requestRefresh();
  };
  
  var TH_CustomPageConditions_GameActor_learnSkill = Game_Actor.prototype.learnSkill;
  Game_Actor.prototype.learnSkill = function(skillId) {
    TH_CustomPageConditions_GameActor_learnSkill.call(this, skillId);
    $gameMap.requestRefresh();
  };
  
  var TH_CustomPageConditions_GameBattler_refresh = Game_Battler.prototype.refresh;
  Game_Battler.prototype.refresh = function() {
    TH_CustomPageConditions_GameBattler_refresh.call(this);
    $gameMap.requestRefresh();
  };
})(TH.CustomPageConditions);